import os
from flask import Blueprint, request, jsonify, current_app
from models.status import Status
from components.exts import db
from utils.File2DatabaseUtil import File2DatabaseUtil
from utils.UUIDGenerator import UUIDGenerator
from components import resDTO, errDTO
import threading

statusBlueprint = Blueprint('status', __name__, url_prefix='/graph/excel')
uuidGenerator = UUIDGenerator()
file2db = File2DatabaseUtil()


# 查询指定文件处理状态
@statusBlueprint.route('/query_status_byId', methods=['POST'])
def batch_status():
    """
        查询上传的excel文件处理状态
        ---
        tags:
          - excel文件处理接口
        description:
            查询上传文件的处理状态，状态分为：已接收、处理中、处理完成
        parameters:
          - name: ids
            in: body
            description: 文件id列表
            required: true
            schema:
              id: ids
              type: object
              properties:
                ids:
                  type: array
                  items:
                    schema:
                      id: id_item
                      type: string
        responses:
          200:
            description: 响应成功
    """
    data = request.get_json()
    ids = data.get('ids')
    results = Status.query.filter(Status.file_uuid.in_(ids)).all()
    res = []
    for item in results:
        res.append({
            "file_name": item.file_name,
            "file_uuid": item.file_uuid,
            "status": item.file_status.value
        })
    return resDTO(data=res)


@statusBlueprint.route('/query_status_all', methods=['POST'])
def queryAllStatus():
    """
        查询所有上传的excel文件的处理状态
        ---
        tags:
          - excel文件处理接口
        description:
            查询上传文件的处理状态，状态分为：已接收、处理中、处理完成
        responses:
          200:
            description: 响应成功
    """
    results = Status.query.all()
    res = []
    for item in results:
        res.append({
            "file_name": item.file_name,
            "file_uuid": item.file_uuid,
            "status": item.file_status.value
        })
    return resDTO(data=res)


@statusBlueprint.post('/handle_file')
def handle_file():
    """
        上传文件进行处理
        ---
        tags:
          - excel文件处理接口
        description:
            上传文件进行处理
        consumes: [
              "multipart/form-data"
            ]
        parameters:
          - name: file
            in: formData
            description: excel文件
            required: true
            type: file
        responses:
          200:
            description: 响应成功
    """
    file = request.files['file']
    if file:
        file_uuid = uuidGenerator.generate_uuid()
        file_name = file.filename
        cur_dir = os.path.abspath(os.path.dirname(__file__))
        cur_dir = os.path.abspath(os.path.join(cur_dir, os.pardir))
        save_addr = os.path.join(cur_dir, 'file_cache')
        if not os.path.exists(save_addr):
            os.makedirs(save_addr)
        save_path = os.path.join(cur_dir, 'file_cache', fr'{file_uuid}.xlsx')
        file.save(save_path)
        s = Status(file_name=file_name, file_uuid=file_uuid)
        db.session.add(s)
        db.session.commit()
        s.change_status()
        try:
            # 启动新的线程处理文件
            # 异步处理,需要将当前app以及上下文作为参数传给子进程
            app = current_app._get_current_object()
            threading.Thread(target=file2db.import_file, args=(save_path, s.id, app, )).start()
            res = {
                "filename": file_name,
                "file_uuid": file_uuid,
                "status": "已接收"
            }
            return resDTO(msg="接收成功", data=res)
        except Exception as e:
            s.status2err()
            print(e)
